package ws.performancetest.api;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.List;
import org.hyperic.sigar.SigarException;
import ws.utils.jdbc.DBConnection;
import ws.utils.jdbc.DBManager;

/**
 * Representation of system information on a database.
 * This class has methods to insert system information into a database, check
 * if a system information already existsTable on the database and retrieve all
 * system information from the database.
 * 
 * @author Wilson Santos, 36228 <wilson.santos@ua.pt>
 */
public class DBSystemInfo extends SystemInfo {

  /** Name of the table that stores the system information. */
  private String table = "SystemInfo";
  /** System information table entry ID. */
  private Integer ID = null;

  /**
   * Create new instance.
   *
   * If your choose to postpone the information gathering, you can then use
   * the method {@link #gatherSystemInformation()}.
   *
   * @param autogather if {@code true} the system information will be gathered
   * automatically on object creation, otherwise the object if created will {@code NULL}
   * information.
   * 
   * @throws SigarException
   */
  public DBSystemInfo(boolean autogather) throws SigarException {
    super(autogather);
  }

  /**
   * Insert this {@code SystemInfo} object to the database.
   * If the object already existsTable on the database no new entry is created and
   * the id return is the id of the entry that equals this system information.
   * 
   * @return id of the entry inserted.
   */
  public Integer insert() throws SQLException {
    ID = find();
    if (ID == null) {
      String sql = "INSERT INTO " + table + " (Name, CPU, RAM, OperatingSystem) "
              + "VALUES (?, ?, ?, ?)";
      Connection con = DBConnection.getDBCon();
      PreparedStatement stmt = con.prepareCall(sql);
      stmt.setString(1, name);
      stmt.setString(2, cpu);
      stmt.setString(3, ram);
      stmt.setString(4, operatingSystem);
      stmt.executeUpdate();

      DBManager dbmanager = new DBManager();
      ID = dbmanager.getIdentity();
    }
    return ID;
  }

  /**
   * Check if this system information already existsTable on the database.
   * If it existsTable the {@code ID} is assigned to the ID of the entry found.
   * The check is done using the host name.
   *
   * @return id of the found object, otherwise returns {@code NULL}.
   * 
   * @throws SQLException
   */
  public Integer find() throws SQLException {
    String sql = "SELECT dbo.udf_SystemInfo_find('" + name + "')";
    Connection con = DBConnection.getDBCon();
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(sql);
    if (rs.next()) {
      ID = rs.getInt(1);
      if (rs.wasNull()) {
        ID = null;
      }
    }
    return ID;
  }

  public List<SystemInfo> selectAll() throws SQLException, SigarException {
    List<SystemInfo> list = new LinkedList<SystemInfo>();
    String sql = "SELECT Name, CPU, RAM, OperatingSystem FROM " + table;
    Connection con = DBConnection.getDBCon();
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(sql);
    while (rs.next()) {
      SystemInfo info = new SystemInfo(false);
      info.setName(rs.getString(1));
      info.setCpu(rs.getString(2));
      info.setRam(rs.getString(3));
      info.setOperatingSystem(rs.getString(4));

      list.add(info);
    }
    return list;
  }

  /**
   * Get property.
   *
   * @return System information table entry ID.
   */
  public Integer getID() {
    return ID;
  }
}
